package com.xzzz.irda.guardcat.core.metric;

import cn.hutool.core.util.StrUtil;
import com.xzzz.common.base.exception.XzException500;
import com.xzzz.irda.guardcat.core.metric.bufferpool.BufferPoolInfo;
import com.xzzz.irda.guardcat.core.metric.classloading.ClassLoadingInfo;
import com.xzzz.irda.guardcat.core.metric.gc.GarbageCollectorInfo;
import com.xzzz.irda.guardcat.core.metric.threadpool.CustomThreadPoolInfo;
import com.xzzz.irda.guardcat.core.metric.tomcat.*;
import com.xzzz.irda.guardcat.core.metric.compiler.CompilerInfo;
import com.xzzz.irda.guardcat.core.metric.druid.DruidConnectionPoolInfo;
import com.xzzz.irda.guardcat.core.metric.dubbo.DubboThreadPoolInfo;
import com.xzzz.irda.guardcat.core.metric.jvm.JvmInfo;
import com.xzzz.irda.guardcat.core.metric.memory.BaseMemoryUsageInfo;
import com.xzzz.irda.guardcat.core.metric.memory.JvmMemoryInfo;
import com.xzzz.irda.guardcat.core.metric.memory.MemoryInfo;
import com.xzzz.irda.guardcat.core.metric.memory.MemoryUsageInfo;
import com.xzzz.irda.guardcat.core.metric.system.OperatingSystemInfo;
import com.xzzz.irda.guardcat.core.metric.thread.JvmThreadInfo;
import com.xzzz.irda.guardcat.core.metric.thread.ThreadMsg;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

/**
 * 【Core】Jvm信息
 *
 * @author xzzz
 * 
 */
@RestController
@RequestMapping("/guardcat/core/jvm")
public class GuardcatJvmController {

    /**
     * 操作系统信息
     *
     * @return OperatingSystemInfo
     */
    @GetMapping(value = "/getOperatingSystemInfo")
    public static OperatingSystemInfo getOperatingSystemInfo() {
        return JvmUtil.getOperatingSystemInfo();
    }

    /**
     * 类加载信息
     *
     * @return ClassLoadingInfo
     */
    @GetMapping(value = "/getClassLoadingInfo")
    public static ClassLoadingInfo getClassLoadingInfo() {
        return JvmUtil.getClassLoadingInfo();
    }

    /**
     * 编译器信息
     *
     * @return CompilerInfo 编译器信息
     */
    @GetMapping(value = "/getCompilerInfo")
    public static CompilerInfo getCompilerInfo() {
        return JvmUtil.getCompilerInfo();
    }

    /**
     * JVM信息
     *
     * @return JvmInfo JVM 信息
     */
    @GetMapping(value = "/getJvmInfo")
    public static JvmInfo getJvmInfo() {
        return JvmUtil.getJvmInfo();
    }

    /**
     * JVM进程Id
     *
     * @return String 进程 Id
     */
    @GetMapping(value = "/getJvmProcessId")
    public static String getJvmProcessId() {
        return JvmUtil.getJvmProcessId();
    }

    /**
     * JVM堆中对象统计信息
     *
     * @return String 统计信息
     * @apiNote 等价于使用命令行：jmap -histo pid
     */
    @GetMapping(value = "/getHeapMemoryObjectStatistics")
    public static String getHeapMemoryObjectStatistics() {
        try {
            return JvmUtil.getHeapMemoryObjectStatistics("");
        } catch (NoClassDefFoundError error) {
            throw new XzException500("下载文件时发生异常：" + error.getMessage());
        }
    }

    /**
     * 通过 Jcmd 执行命令
     *
     * @param command 命令
     * @return String 执行结果
     */
    @GetMapping(value = "/executeCommandByJcmd")
    public static String executeCommandByJcmd(String command) {
        if (StrUtil.isEmpty(command)) {
            return null;
        }
        return JvmUtil.executeCommandByJcmd(command);
    }

    /**
     * 简单的线程信息
     *
     * @return JvmThreadInfo Jvm 线程信息
     */
    @GetMapping(value = "/getSimpleJvmThreadInfo")
    public static JvmThreadInfo getSimpleJvmThreadInfo() {
        try {
            return JvmUtil.getSimpleJvmThreadInfo();
        } catch (NoClassDefFoundError error) {
            throw new XzException500("下载文件时发生异常：" + error.getMessage());
        }
    }

    /**
     * 所有线程堆栈信息
     *
     * @return String 线程堆栈信息
     * @apiNote 等价于使用命令行：jstack pid
     */
    @GetMapping(value = "/getFullThreadDumpMsg")
    public static String getFullThreadDumpMsg() {
        try {
            return JvmUtil.getFullThreadDumpMsg("");
        } catch (NoClassDefFoundError error) {
            throw new XzException500("下载文件时发生异常：" + error.getMessage());
        }
    }

    /**
     * 根据线程Id获取线程信息
     *
     * @param threadId 线程Id
     * @return ThreadMsg 线程信息
     */
    @GetMapping(value = "/getThreadMsgByThreadId")
    public static ThreadMsg getThreadMsgByThreadId(Long threadId) {
        if (null == threadId) {
            return null;
        }
        return JvmUtil.getThreadMsgByThreadId(threadId);
    }

    /**
     * 所有的线程信息
     *
     * @return Set<ThreadMsg>
     */
    @GetMapping(value = "/getAllThreadMsgSet")
    public static Set<ThreadMsg> getAllThreadMsgSet() {
        return JvmUtil.getAllThreadMsgSet();
    }

    /**
     * 所有死锁线程信息
     *
     * @return Set<ThreadMsg>
     * @apiNote 【包含 synchronized 死锁 和 通过 AbstractQueuedSynchronizer 实现的锁的死锁】
     */
    @GetMapping(value = "/getDeadlockedThreadMsgSet")
    public static Set<ThreadMsg> getDeadlockedThreadMsgSet() {
        return JvmUtil.getDeadlockedThreadMsgSet();
    }

    /**
     * 所有synchronized死锁线程
     *
     * @return Set<ThreadMsg>
     */
    @GetMapping(value = "/getMonitorDeadlockedThreadMsgSet")
    public static Set<ThreadMsg> getMonitorDeadlockedThreadMsgSet() {
        return JvmUtil.getMonitorDeadlockedThreadMsgSet();
    }

    /**
     * 堆/非堆信息
     *
     * @return JvmMemoryInfo  JVM 内存信息
     */
    @GetMapping(value = "/getJvmMemoryInfo")
    public static JvmMemoryInfo getJvmMemoryInfo() {
        return JvmUtil.getJvmMemoryInfo();
    }

    /**
     * 堆内存使用信息
     *
     * @return BaseMemoryUsageInfo 基础内存使用信息
     */
    @GetMapping(value = "/getHeapMemoryUsageInfo")
    public static BaseMemoryUsageInfo getHeapMemoryUsageInfo() {
        return JvmUtil.getHeapMemoryUsageInfo();
    }

    /**
     * 非堆内存使用信息
     *
     * @return BaseMemoryUsageInfo 基础内存使用信息
     */
    @GetMapping(value = "/getNonHeapMemoryUsageInfo")
    public static BaseMemoryUsageInfo getNonHeapMemoryUsageInfo() {
        return JvmUtil.getNonHeapMemoryUsageInfo();
    }

    /**
     * JIT编译代码缓存区内存内存使用信息
     *
     * @return MemoryUsageInfo  内存使用信息
     */
    @GetMapping(value = "/getCodeCacheMemoryUsageInfo")
    public static MemoryUsageInfo getCodeCacheMemoryUsageInfo() {
        return JvmUtil.getCodeCacheMemoryUsageInfo();
    }

    /**
     * 元空间内存使用信息
     *
     * @return MemoryUsageInfo  内存使用信息
     */
    @GetMapping(value = "/getMetaspaceMemoryUsageInfo")
    public static MemoryUsageInfo getMetaspaceMemoryUsageInfo() {
        return JvmUtil.getMetaspaceMemoryUsageInfo();
    }

    /**
     * 类压缩数据区内存使用信息
     *
     * @return MemoryUsageInfo  内存使用信息
     */
    @GetMapping(value = "/getCompressedClassSpaceMemoryUsageInfo")
    public static MemoryUsageInfo getCompressedClassSpaceMemoryUsageInfo() {
        return JvmUtil.getCompressedClassSpaceMemoryUsageInfo();
    }

    /**
     * 新生代内存使用信息
     *
     * @return MemoryUsageInfo  内存使用信息
     */
    @GetMapping(value = "/getEdenSpaceMemoryUsageInfo")
    public static MemoryUsageInfo getEdenSpaceMemoryUsageInfo() {
        return JvmUtil.getEdenSpaceMemoryUsageInfo();
    }

    /**
     * JVM幸存代内存使用信息
     *
     * @return MemoryUsageInfo  内存使用信息
     */
    @GetMapping(value = "/getSurvivorSpaceMemoryUsageInfo")
    public static MemoryUsageInfo getSurvivorSpaceMemoryUsageInfo() {
        return JvmUtil.getSurvivorSpaceMemoryUsageInfo();
    }

    /**
     * 老年代内存使用信息
     *
     * @return MemoryUsageInfo  内存使用信息
     */
    @GetMapping(value = "/getOldGenMemoryUsageInfo")
    public static MemoryUsageInfo getOldGenMemoryUsageInfo() {
        return JvmUtil.getOldGenMemoryUsageInfo();
    }

    /**
     * 所有的内存信息
     *
     * @return MemoryInfo 内存信息
     */
    @GetMapping(value = "/getMemoryInfo")
    public static MemoryInfo getMemoryInfo() {
        return JvmUtil.getMemoryInfo();
    }

    /**
     * 缓冲池信息
     *
     * @return BufferPoolInfo 缓冲池信息
     * @apiNote nio中的直接内存信息
     */
    @GetMapping(value = "/getBufferPoolInfo")
    public static BufferPoolInfo getBufferPoolInfo() {
        return JvmUtil.getBufferPoolInfo();
    }

    /**
     * 垃圾收集器信息
     *
     * @return List<GarbageCollectorInfo>
     * @apiNote 触发GC之后才会有信息
     */
    @GetMapping(value = "/getGarbageCollectorInfos")
    public static List<GarbageCollectorInfo> getGarbageCollectorInfos() {
        return JvmUtil.getGarbageCollectorInfos();
    }


    /**
     * Tomcat服务器信息
     *
     * @return List<TomcatServerInfo>
     */
    @GetMapping(value = "/getTomcatServerInfos")
    public static List<TomcatServerInfo> getTomcatServerInfos() {
        return JvmUtil.getTomcatServerInfos();
    }

    /**
     * Tomcat全局请求处理器监控信息
     *
     * @return List<TomcatGlobalRequestProcessorInfo>
     */
    @GetMapping(value = "/getTomcatGlobalRequestProcessorInfos")
    public static List<TomcatGlobalRequestProcessorInfo> getTomcatGlobalRequestProcessorInfos() {
        return JvmUtil.getTomcatGlobalRequestProcessorInfos();
    }

    /**
     * Tomcat连接器监控信息
     *
     * @return List<TomcatConnectorInfo>
     */
    @GetMapping(value = "/getTomcatConnectorInfos")
    public static List<TomcatConnectorInfo> getTomcatConnectorInfos() {
        return JvmUtil.getTomcatConnectorInfos();
    }

    /**
     * Tomcat协议处理器监控信息
     *
     * @return List<TomcatProtocolHandlerInfo>
     */
    @GetMapping(value = "/getTomcatProtocolHandlerInfos")
    public static List<TomcatProtocolHandlerInfo> getTomcatProtocolHandlerInfos() {
        return JvmUtil.getTomcatProtocolHandlerInfos();
    }

    /**
     * Tomcat线程池监控信息
     *
     * @return List<TomcatThreadPoolInfo>
     */
    @GetMapping(value = "/getTomcatThreadPoolInfos")
    public static List<TomcatThreadPoolInfo> getTomcatThreadPoolInfos() {
        return JvmUtil.getTomcatThreadPoolInfos();
    }

    /**
     * Tomcat中DispatcherServletInfo的监控
     *
     * @return List<TomcatDispatcherServletInfo>
     */
    @GetMapping(value = "/getTomcatDispatcherServletInfos")
    public static List<TomcatDispatcherServletInfo> getTomcatDispatcherServletInfos() {
        return JvmUtil.getTomcatDispatcherServletInfos();
    }

    /**
     * 获取自定义线程池的监控信息
     *
     * @return List<CustomThreadPoolInfo>
     */
    @GetMapping(value = "/getCustomThreadPoolInfos")
    public static List<CustomThreadPoolInfo> getCustomThreadPoolInfos() {
        return JvmUtil.getCustomThreadPoolInfos();
    }

    /**
     * 获取Dubbo线程池监控
     *
     * @return List<DubboThreadPoolInfo>
     */
    @GetMapping(value = "/getApacheDubboThreadPoolInfos")
    @SuppressWarnings("all")
    public static List<DubboThreadPoolInfo> getApacheDubboThreadPoolInfos() {
        return JvmUtil.getApacheDubboThreadPoolInfos();
    }

    /**
     * 获取Druid连接池信息
     *
     * @return DruidConnectionPoolInfo
     */
    @GetMapping(value = "/getDruidConnectionPoolInfo")
    public static DruidConnectionPoolInfo getDruidConnectionPoolInfo() {
        return JvmUtil.getDruidConnectionPoolInfo();
    }

}
